#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

extern char **environ;

int do_print(char **p)
{
	if (!p) {
		printf("Param error\n");
		return -1;
	}
	char **ptr = p;
	while (*ptr != NULL) {
		printf("%s\n", *ptr);
		ptr++;
	}
	return 0;
}

int main(int argc, char **argv)
{
	int opt, i, j;
	int flag = 0;
	int nr_env = 0;
	int sys_flag = 0;
	char *p_exec;
	char **_environ = environ;
	char **__environ = environ;

	if (argc == 1) {
		if (-1 == do_print(environ)) {
			exit(EXIT_FAILURE);
		}
		exit(EXIT_SUCCESS);
	}

	while ((opt = getopt(argc, argv, "i")) != -1) {
		switch (opt) {
		case 'i': 
			flag = 1; break;
		default: break;
		}
	}

	while (*__environ != NULL) {
		nr_env++;
		__environ++;
	}
	
	if (flag == 1) {
		environ = (char **)malloc(sizeof(void *) * argc);
		memset(environ, 0, sizeof(void *) * argc);
		char **p_env = environ;
		char **_argv = argv + 1;
		while (*_argv != NULL) {
			if (**_argv == '.' || **_argv == '/') {
				sys_flag = 1;
				p_exec = *_argv;
				_argv++;
				continue;
			} else {
				char *t = *_argv;
				int f = 0;
				while (*t != '\0') {
					if (*t == '=') {
						f = 1;
						break;
					}
					t++;
				}
				if (f == 1) {
					*p_env = *_argv;
					p_env++;
				} else {
					if (strcmp(*_argv, "-i")) {
						sys_flag = 1;
						p_exec = *_argv;
					}
				}
			}
			_argv++;
		}
		*p_env = NULL;
	} else {
		_environ = (char **)malloc(sizeof(void *) * (nr_env + argc));
		for (i = 0; i < nr_env; i++) {
			_environ[i] = environ[i];
		}
		_environ[i + 1] = NULL;
		int count = 0;
		for (i = 1; i < argc; i++) {
			int s_flag = 0;
			for (j = 0; j < nr_env; j++) {
				char *s1 = (char *)malloc(strlen(argv[i]) + 1);
				char *s2 = (char *)malloc(strlen(_environ[j]) + 1);
				strcpy(s1, argv[i]);
				strcpy(s2, _environ[j]);
				if (!strcmp(strtok(s1, "="), strtok(s2, "="))) {
					_environ[j] = argv[i];
					s_flag = 1;
				}
				free(s1);
				free(s2);
			}
			if (s_flag == 0) {
				char *t = argv[i];
				int f = 0;
				while (*t != '\0') {
					if (*t == '=') {
						f = 1;
						break;
					}
					t++;
				}
				if (f == 1) {
					_environ[nr_env + count] = argv[i];
					_environ[nr_env + count + 1] = NULL;
					count++;
				} else {
					sys_flag = 1;
					p_exec = argv[i];
				}
			}
		}
		environ = _environ;
	}
	
	if (sys_flag == 0) {
		do_print(environ);
	} else {
		system(p_exec);
	}

	return 0;
}
